use chrono::{DateTime as CDateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use wither::{
    bson::{oid::ObjectId, DateTime, Document},
    Model,
};

use super::ClubFormStatusFlow;
mod serde_default {
    use super::*;
    pub fn club_form_type() -> ClubFormType {
        ClubFormType::Normal
    }
    pub fn club_form_allow_repeat() -> bool {
        false
    }
    pub fn club_form_allow_rewrite() -> bool {
        false
    }
}

/// ## ClubFormType
/// 表单类型
#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum ClubFormType {
    /// ### Join
    /// 纳新表单
    Join = 0,
    /// ### Normal
    /// 普通表单
    Normal = 1,
}

#[derive(Debug, Clone, Serialize, Deserialize, Model)]
pub struct ClubFormModel {
    #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
    pub id: Option<ObjectId>,
    pub club_id: ObjectId,
    pub title: String,
    pub description: Option<String>,
    /// 用于验证表单是否合法的Schema
    pub rule: Option<Document>,
    /// 表单的样式布局
    pub layout: Option<Document>,
    #[serde(rename = "type", default = "serde_default::club_form_type")]
    pub form_type: ClubFormType,
    #[serde(default = "serde_default::club_form_allow_repeat")]
    pub allow_repeat: bool,
    #[serde(default = "serde_default::club_form_allow_rewrite")]
    pub allow_rewrite: bool,
    /// 是否启用此表单
    #[serde(default = "Default::default")]
    pub active: bool,
    /// 软删除
    #[serde(default = "Default::default")]
    pub valid: bool,
    pub created_at: DateTime,
    pub updated_at: DateTime,
    pub status_flow: Option<ClubFormStatusFlow>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClubFormModelDTO {
    pub id: Option<String>,
    pub club_id: String,
    pub title: String,
    pub description: Option<String>,
    pub rule: Option<Document>,
    pub layout: Option<Document>,
    #[serde(rename = "type")]
    pub form_type: ClubFormType,
    pub allow_repeat: bool,
    pub allow_rewrite: bool,
    pub created_at: CDateTime<Utc>,
    pub updated_at: CDateTime<Utc>,
    pub status_flow: Option<ClubFormStatusFlow>,
}

impl From<ClubFormModel> for ClubFormModelDTO {
    fn from(model: ClubFormModel) -> Self {
        Self {
            id: model.id.map(|v| v.to_string()),
            club_id: model.club_id.to_string(),
            title: model.title,
            description: model.description,
            rule: model.rule,
            layout: model.layout,
            form_type: model.form_type,
            allow_rewrite: model.allow_rewrite,
            allow_repeat: model.allow_repeat,
            status_flow: model.status_flow,
            created_at: model.created_at.to_chrono(),
            updated_at: model.updated_at.to_chrono(),
        }
    }
}
